import json

from django.test import TestCase
from django.test import Client
from django.test.client import MULTIPART_CONTENT

from common import constants
from storage.models import VendorProduct


class TestCreateProductApi(TestCase):
    def setUp(self):
        self.client = Client()
        self.uri = '/products'

        self.bar_code = '122'
        self.test_data = {
            'bar_code': self.bar_code,

            'name': '12',
            'vendor_name': '12',
            'brand': '12',
            'ware_id': '12',
            'packing': '12',
            'region': '12',
            'weight': '12',
            'seo_info': '12',
            'properties': None,

        }

    def tearDown(self):
        pass

    def testCreateSuccess(self):
        response = self.client.post(self.uri.format(bar_code=self.bar_code), data=json.dumps(self.test_data),
                                    content_type='application/json')
        self.assertEquals(response.status_code, 200)

    def testCreateErrorExists(self):
        VendorProduct(**self.test_data).save()

        response = self.client.post(self.uri.format(bar_code=self.bar_code), data=json.dumps(self.test_data),
                                    content_type='application/json')

        self.assertEquals(response.status_code, 422)
        self.assertEquals(response.json()['message'], constants.MESSAGE_ALREADY_EXISTS)
        self.assertEquals(response.json()['errors'][0]['code'], constants.ERROR_CODE_ALREADY_EXISTS)

    def testCreateErrorParamsNoBarCode(self):
        test_data = self.test_data
        del test_data['bar_code']

        response = self.client.post(self.uri.format(bar_code=self.bar_code), data=json.dumps(test_data),
                                    content_type='application/json')
        self.assertEquals(response.status_code, 422)
        self.assertEqual(response.json()['message'], constants.MESSAGE_VALIDATE_ERROR)
        self.assertEquals(response.json()['errors'][0]['field'], 'schema')

    def testCreateErrorParamsErrorJson(self):
        response = self.client.post(self.uri.format(bar_code=self.bar_code), data=self.test_data,
                                    content_type=MULTIPART_CONTENT)
        self.assertEquals(response.status_code, 400)

        self.assertEquals(response.json()['message'], constants.MESSAGE_PARSING_ERROR)


class TestQueryProductApi(TestCase):
    def setUp(self):
        self.client = Client()
        self.uri = '/search/products'

        self.bar_code1 = '121'
        self.test_data1 = {
            'bar_code': self.bar_code1,

            'name': '12',
            'vendor_name': '12',
            'brand': '12',
            'ware_id': '12',
            'packing': '12',
            'region': '12',
            'weight': '12',
            'seo_info': '12',
            'properties': '12',

        }
        self.product1 = VendorProduct(**self.test_data1)
        self.product1.save()

        self.bar_code2 = '122'
        self.test_data2 = {
            'bar_code': self.bar_code2,

            'name': '12',
            'vendor_name': '12',
            'brand': '12',
            'ware_id': '12',
            'packing': '12',
            'region': '12',
            'weight': '12',
            'seo_info': '12',
            'properties': '12',

        }
        self.product2 = VendorProduct(**self.test_data2)
        self.product2.save()

        self.bar_code3 = '123'
        self.test_data3 = {
            'bar_code': self.bar_code3,

            'name': '12',
            'vendor_name': '12',
            'brand': '12',
            'ware_id': '12',
            'packing': '12',
            'region': '12',
            'weight': '12',
            'seo_info': '12',
            'properties': '12',

        }
        self.product3 = VendorProduct(**self.test_data3)
        self.product3.save()

    def tearDown(self):
        pass

    def testQuerySuccess(self):
        test_query = ','.join([self.bar_code1, self.bar_code2, self.bar_code3])

        response = self.client.get(self.uri + '?bar_code=' + test_query)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.json()), 3)

    def testQueryNoParams(self):
        response = self.client.get(self.uri)
        self.assertEqual(response.status_code, 400)
        self.assertEquals(response.json()['message'], constants.MESSAGE_MISSING)

    def testQueryListParams2(self):
        response = self.client.get(self.uri+ '?bar_code[]=1&bar_code[]=2')
        self.assertEqual(response.status_code, 400)
        self.assertEquals(response.json()['message'], constants.MESSAGE_MISSING)

    def testQueryListParams3(self):
        response = self.client.get(self.uri+ '?bar_code[0]=1&bar_code[1]=2')
        self.assertEqual(response.status_code, 400)
        self.assertEquals(response.json()['message'], constants.MESSAGE_MISSING)

    def testQueryErrorParamsKey(self):
        response = self.client.get(self.uri + '?bar=')
        self.assertEqual(response.status_code, 400)
        self.assertEquals(response.json()['message'], constants.MESSAGE_MISSING)

    def testQueryErrorParamsValue(self):
        response = self.client.get(self.uri + '?bar_code=')

        self.assertEqual(response.status_code, 400)
        self.assertEquals(response.json()['message'], constants.MESSAGE_MISSING)


class TestUpdateProductApi(TestCase):
    def setUp(self):
        self.client = Client()
        self.uri = '/products/{bar_code}'

        self.bar_code = '122'
        self.test_data = {
            'name': '12',
            'vendor_name': '12',
            'brand': '12',
            'ware_id': '12',
            'packing': '12',
            'region': '12',
            'weight': None,
            'seo_info': '12',
            'properties': '12',

        }
        self.product = VendorProduct(**self.test_data)
        self.product.bar_code = self.bar_code
        self.product.save()

    def tearDown(self):
        pass

    def testUpdateSuccess(self):
        response = self.client.patch(self.uri.format(bar_code=self.bar_code),
                                     data=json.dumps(self.test_data))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(response.json()['bar_code'], self.bar_code)

    def testUpdateErrorNotExists(self):
        self.product.delete()

        response = self.client.patch(self.uri.format(bar_code=self.bar_code), data=json.dumps(self.test_data),
                                     content_type='application/json')
        self.assertEquals(response.status_code, 422)
        self.assertEquals(response.json()['message'], constants.MESSAGE_MISSING)

    def testUpdateErrorMoreBarCode(self):
        test_data = self.test_data
        test_data['bar_code'] = '122'
        response = self.client.patch(self.uri.format(bar_code=self.bar_code), data=json.dumps(test_data),
                                     content_type='application/json')
        self.assertEquals(response.status_code, 422)
        self.assertEquals(response.json()['message'], constants.MESSAGE_VALIDATE_ERROR)

    def testUpdateErrorParams(self):
        test_data = self.test_data
        test_data['weight'] = '2B'
        response = self.client.patch(self.uri.format(bar_code=self.bar_code), data=json.dumps(test_data),
                                     content_type='application/json')
        self.assertEquals(response.status_code, 422)

        self.assertEquals(response.json()['message'], constants.MESSAGE_VALIDATE_ERROR)
        self.assertEquals(response.json()['errors'][0]['field'], 'schema')

    def testUpdateErrorParamsErrorJson(self):
        response = self.client.patch(self.uri.format(bar_code=self.bar_code), data=self.test_data,
                                     content_type=MULTIPART_CONTENT)
        self.assertEquals(response.status_code, 400)

        self.assertEquals(response.json()['message'], constants.MESSAGE_PARSING_ERROR)
